
package SimpleSampleProofOfConcept.gui;

import java.io.*;
import java.lang.Runtime;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;

/**
 *
 * @author jaimes
 * @modified 10-02-14
 * Added Input and ouptut file choosers
 * Added Run button. Call to sox working.
 * 
 */
public class SimpleSampleUI extends javax.swing.JFrame {
    
    private Runtime runtime;
    private Process process;
    private String inputFile;
    private String outputFile;
    // The sample rate to convert to
    private String sampleRate;
    // The bit rate to convert to
    private String bitRate;
    //Create a file chooser to be used as open and save dialogue
    final JFileChooser fileChooser = new JFileChooser();

    /**
     * Creates new form SimpleSampleUI
     */
    public SimpleSampleUI() 
    {
        
        initComponents();
        
        // Default sample rate to convert to 44100Hz
        sampleRate = "22050";
        
        // Default bit rate to convert to 16Bit
        bitRate = "8";
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents()
    {

        jPanel = new javax.swing.JPanel();
        pnlInput = new javax.swing.JPanel();
        txtFieldInput = new javax.swing.JFormattedTextField();
        lblInput = new javax.swing.JLabel();
        pnlOutput = new javax.swing.JPanel();
        txtFieldOutput = new javax.swing.JFormattedTextField();
        lblOutput = new javax.swing.JLabel();
        btnRunSOX = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        pnlInput.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        pnlInput.setName("Input"); // NOI18N

        txtFieldInput.setText("inputFilePath");
        txtFieldInput.addMouseListener(new java.awt.event.MouseAdapter()
        {
            public void mouseClicked(java.awt.event.MouseEvent evt)
            {
                inputTextFieldClicked(evt);
            }
        });

        lblInput.setText("Input");

        javax.swing.GroupLayout pnlInputLayout = new javax.swing.GroupLayout(pnlInput);
        pnlInput.setLayout(pnlInputLayout);
        pnlInputLayout.setHorizontalGroup(
            pnlInputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlInputLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlInputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtFieldInput, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(pnlInputLayout.createSequentialGroup()
                        .addComponent(lblInput)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        pnlInputLayout.setVerticalGroup(
            pnlInputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlInputLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblInput)
                .addGap(18, 18, 18)
                .addComponent(txtFieldInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(26, Short.MAX_VALUE))
        );

        pnlOutput.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        pnlOutput.setName("Input"); // NOI18N

        txtFieldOutput.setText("outputFilePath");
        txtFieldOutput.addMouseListener(new java.awt.event.MouseAdapter()
        {
            public void mouseClicked(java.awt.event.MouseEvent evt)
            {
                outputTextFieldClicked(evt);
            }
        });

        lblOutput.setText("Output");

        javax.swing.GroupLayout pnlOutputLayout = new javax.swing.GroupLayout(pnlOutput);
        pnlOutput.setLayout(pnlOutputLayout);
        pnlOutputLayout.setHorizontalGroup(
            pnlOutputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlOutputLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlOutputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtFieldOutput, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 415, Short.MAX_VALUE)
                    .addGroup(pnlOutputLayout.createSequentialGroup()
                        .addComponent(lblOutput)
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        pnlOutputLayout.setVerticalGroup(
            pnlOutputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnlOutputLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblOutput)
                .addGap(18, 18, 18)
                .addComponent(txtFieldOutput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(26, Short.MAX_VALUE))
        );

        btnRunSOX.setText("Run SOX");
        btnRunSOX.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                RunSoxButtonClicked(evt);
            }
        });

        javax.swing.GroupLayout jPanelLayout = new javax.swing.GroupLayout(jPanel);
        jPanel.setLayout(jPanelLayout);
        jPanelLayout.setHorizontalGroup(
            jPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(pnlInput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelLayout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(btnRunSOX)))
                .addContainerGap())
        );
        jPanelLayout.setVerticalGroup(
            jPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(pnlInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(pnlOutput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(btnRunSOX)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jMenu1.setText("File");

        jMenuItem1.setText("Quit");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                menuQuitActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void menuQuitActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_menuQuitActionPerformed
    {//GEN-HEADEREND:event_menuQuitActionPerformed
        // TODO: Close terminal on quit
        
        // Quit simpleSample
        System.exit(0);
    }//GEN-LAST:event_menuQuitActionPerformed

    /**
     * Passes the parameters to the SOX SOund eXchange command for processing 
     * when "Run Sox" button is clicked.
     * @param evt 
     */
    private void RunSoxButtonClicked(java.awt.event.ActionEvent evt)//GEN-FIRST:event_RunSoxButtonClicked
    {//GEN-HEADEREND:event_RunSoxButtonClicked
        // Test running a command in terminal
        // http://stackoverflow.com/questions/597927/how-to-open-a-command-terminal-in-linux
        
        // Sox Resampler library
        // http://sourceforge.net/p/soxr/wiki/Home/
        
        // Calliing C code directly
        // http://stuf.ro/calling-c-code-from-java-using-jna
        
        System.out.println("Run Sox Pressed");
        try
        {   
            // The -e option can be used to invoke either a script or another program.
            
            // TODO: Run command in shell so user can see the process.
            //String[] commandArray = {"xterm"}; // Lowest common denominator shell.
            //String[] commandArray = {"xterm", "-e", "sox"}; // Lowest common denominator shell.
            
            // Create an array containing the parameters to process externally (in terminal?)
            // For testing a bit rate matching the inputfile and a sample rate of 22050Hz is hard coded.
            // There seems to be a sample rate cut off < 3000Hz, where the outputFile 
            // does not produce sound in VLC.
            String[] commandArray = {"sox", inputFile, "-b", bitRate, outputFile, "rate", sampleRate};
            
            runInTerminal(commandArray);
            System.out.println("Sent for processing");
            
        } catch (IOException ex)
        {
            Logger.getLogger(SimpleSampleUI.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
    }//GEN-LAST:event_RunSoxButtonClicked

    
    /**
     * Opens a file chooser dialogue to select an input file when the input text field is clicked.
     * @param evt The mouse click event which triggers the file chooser
     */
    private void inputTextFieldClicked(java.awt.event.MouseEvent evt)//GEN-FIRST:event_inputTextFieldClicked
    {//GEN-HEADEREND:event_inputTextFieldClicked
        
        
        // In response to clicking the input field:
        // Create a file chooser
        final JFileChooser fileChooser = new JFileChooser();
        
        // Open file chooser and store it's return value.
        int returnValue = fileChooser.showOpenDialog(this);
        
        //Handle open button action.
        // If a file is selected
        if (returnValue == JFileChooser.APPROVE_OPTION)
        {
            // Get the selected file
            File file = fileChooser.getSelectedFile();
            
            // Set the inputFile variable to the selected file
            //inputFile = file.getName();
            inputFile = file.getPath();
            
            // Set the input text field to inputFile
            txtFieldInput.setText(inputFile);
            
            System.out.println("Input File set to " + inputFile);
            
        }
        // Otherwise, handle cancelled open dialogue.
        else 
        {
            
            System.out.println("Open command cancelled by user.");
                    
        }
        
    }//GEN-LAST:event_inputTextFieldClicked

    
    /**
     * Opens a file chooser dialogue to select an output file when the output text field is clicked.
     * @param evt The mouse click event which triggers the file chooser
     */
    private void outputTextFieldClicked(java.awt.event.MouseEvent evt)//GEN-FIRST:event_outputTextFieldClicked
    {//GEN-HEADEREND:event_outputTextFieldClicked
        // In response to clicking the output text field:
        // Create a file chooser
        //final JFileChooser fileChooser = new JFileChooser();
        
        // Open file chooser and store it's return value.
        int returnValue = fileChooser.showSaveDialog(this);
        
        //Handle open button action.
        // If a file is selected
        if (returnValue == JFileChooser.APPROVE_OPTION)
        {
            // Get the selected file
            File file = fileChooser.getSelectedFile();
            
            // Set the outputFile variable to the selected file
            //inputFile = file.getName();
            outputFile = file.getPath();
            
            // Set the input text field to inputFile
            txtFieldOutput.setText(outputFile);
            
            System.out.println("Output file set to " + outputFile);
            
        }
        // Otherwise, handle cancelled open dialogue.
        else 
        {
            
            System.out.println("Output selection cancelled by user.");
                    
        }
    }//GEN-LAST:event_outputTextFieldClicked

    public static void runInTerminal(String[] commandArray) throws IOException
    {

            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(commandArray);

    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(SimpleSampleUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(SimpleSampleUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(SimpleSampleUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(SimpleSampleUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new SimpleSampleUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnRunSOX;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JPanel jPanel;
    private javax.swing.JLabel lblInput;
    private javax.swing.JLabel lblOutput;
    private javax.swing.JPanel pnlInput;
    private javax.swing.JPanel pnlOutput;
    private javax.swing.JFormattedTextField txtFieldInput;
    private javax.swing.JFormattedTextField txtFieldOutput;
    // End of variables declaration//GEN-END:variables
}
